package edu.bu.cs511.p5;

/** 
 * Scheduler interface.  Includes all the methods required to manage
 * multiple tasks and to interface with the SchedTasks schedulers are
 * associated with.
 */
public interface IScheduler {
    /**
     * See the representation invariants of children classes.
     */
    public boolean repOk();

    /**
     * Add a new task to this scheduler's structures.  Specify a
     * proportion that task is to have.<p/>
     *
     * @MODIFIES add the task t to the waitingList of this scheduler.
     * <p/>
     * @REQUIRES t is a Task that is not a ThreadManager
     * <p/>
     * @EFFECTS return true if the task was successfully added, false if
     * not.
     */
    public boolean addTask(Task t);

    /**
     * Add a new task to this scheduler's structures.  Specify a
     * proportion that task is to have.<p/>
     *
     * @REQUIRES t is the task to be added to the scheduler's
     * queues. spec is a scheduler specific specification for service
     * in the format of a string.  See the documentation for specific
     * schedulers for more information.<p/>
     *
     * @MODIFIES adds the task to the waitingList of this scheduler.
     * <p/>
     * 
     * @EFFECTS return true if the task was successfully added, false if
     * not.
     */
    public boolean addTask(Task t, String spec);

    /**
     * Remove a given task from the scheduler's structures.  <p/>
     *
     * @REQUIRES task t must be in the scheduler's structures.<p/>
     *
     * <p/>
     * @MODIFIES remove the task t from the scheduler's structures.
     */
    public void removeTask(Task t);

    /**
     * When a scheduler is created, it might be passed in a string that contains
     * the scheduling policy-specific initialization information.<p/>
     *
     * @REQUIRES s is the specification string to initialize the
     * scheduler with.
     */
    public void initString(String s);


    /** 
     * Terminate this scheduler by deallocating all of its data and
     * informing any tasks as needed. <p/>
     *
     * @MODIFIES Deallocates all datastructures associated with this
     * scheduler.
     */
    public void terminateScheduler();


    /**
     * Make a scheduling decision.  This will include choosing a
     * single task which is to execute next out of all tasks the
     * scheduler is tracking.<p/>
     *
     * @REQUIRES there are tasks to be run.<p/>
     *
     * @EFFECTS return the task that should be run next.  null if
     * there was a race condition between the concurrency value and
     * the deletion of a task.  null should be taken to mean "there is
     * nothing to schedule".
     */
    public Task schedule();


    /**
     * This method is invoked by the SchedTask owning this scheduler
     * every time that the task which this scheduler told it to
     * execute (returned from scheduler) has finished executing,
     * ie. the job finished.  This method is used to clean up and
     * update state.<p/>
     *
     * @REQUIRES t must have been the last task returned by
     * schedule(); blocked is true if it cannot compute further at
     * this time (ie. it is blocked). <p/>
     *
     * @MODIFIES if the task t is blocked, make policy decisions
     * appropriately.
     */
    public void jobFinished(Task t, boolean blocked);


    /**
     * Compute the current concurrency level observed at this
     * scheduler (ie. the the minimum of number of threads that have
     * been requested by this scheduler's children and the maximum
     * allowable concurrency for this scheduler.)  <p/>
     *
     * @REQUIRES child might be null, concurrency is the concurrency of the
     * child. <p/>
     *
     * @EFFECTS return the currently observed concurrency which is the
     * minimum of sum of the requested concurrency of each child, and
     * the maximum allowable concurrency at this scheduler.  This will
     * change as opcodes are enabled (increase), and as they run
     * (decrease).
     */
    public int setChildConcurrencyLevel(Task child, int concurrency);

    /**
     * Get the concurrency level of a specific child.<p/>
     *
     * @REQUIRES child is the task to get the concurrency of.<p/>
     *
     * @EFFECTS is the concurrency level of child.
     */
    public int getChildConcurrencyLevel(Task child);

    /**
     * Simply for use to recalculate concurrency level for this
     * schedulre and return it.
     *
     * @EFFECTS return the concurrency level at this scheduler
     */
    public int getThisConcurrencyLevel();
}
